package cn.com.haopy.yue.ai.wx.service;


import cn.com.haopy.yue.ai.core.utils.ConstDateFormatUtils;
import cn.com.haopy.yue.ai.core.utils.ResponseUtil;
import cn.com.haopy.yue.ai.db.entity.arisk.*;
import cn.com.haopy.yue.ai.db.service.hos.*;
import cn.com.haopy.yue.ai.wx.utils.AIChatParseDataUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.*;


/**
 * @author keel
 * @date 2022/4/13
 */
@Service
@Slf4j
public class WxAIRiskPapersService {

    @Autowired
    AIRiskPapersService riskPapersService;

    @Autowired
    AIRiskPapersOptionsService riskPapersOptionsService;

    @Autowired
    AIRiskTopicService riskTopicService;

    @Autowired
    AIRiskTopicOptionsService riskTopicOptionsService;

    @Autowired
    AIRiskPapersIllnessService riskPapersIllnessService;

    @Autowired
    AIRiskIllnessService riskIllnessService;

    @Autowired
    PaperIllnessToAISyncService paperIllnessToAISyncService;

    @Autowired
    AIRiskIllnessTopicService riskIllnessTopicService;

    @Autowired
    AIRiskIllnessCheckIndexService riskIllnessCheckIndexService;

    @Autowired
    AIRiskCheckIndexService riskCheckIndexService;

    @Autowired
    AIRiskPapersIndexService riskPapersIndexService;

    @Autowired
    CheckReportService checkReportService;

    @Autowired
    WxPapersDrugsService wxPapersDrugsService;

    @Autowired
    WxCommonCheckIndexService wxCommonCheckIndexService;


    /**
    @Transactional
    public Object createPaper1(Integer userId, WxReqPaperDto wxReqPaperDto) throws Exception {

        //昊邦体检库数据
        JSONObject haopyReporData = checkReportService.checkDetailData(wxReqPaperDto.getCheckNo());


        AIRiskPapers papers = new AIRiskPapers();
        papers.setName(wxReqPaperDto.getName());
        papers.setUserId(userId);
        papers.setMobile(wxReqPaperDto.getMobile());
        papers.setCheckDate(wxReqPaperDto.getCheckDate());
        papers.setCheckNo(wxReqPaperDto.getCheckNo());
        papers.setAge(wxReqPaperDto.getAge());
        papers.setSex(wxReqPaperDto.getSex());

        papers.setIndexParams(haopyReporData);


        riskPapersService.save(papers);


        //*****************创建问卷选项**********************

        List<AIRiskPapersOptions> listOptionsSave = createPaperTopicOptions(papers);

        //批量保存
        riskPapersOptionsService.saveBatch(listOptionsSave);

        //*****************创建问卷指标**********************


        //List<AIRiskIllness> illnessList = riskIllnessService.listActiveSex(sex);


        List<AIRiskPapersIndex> paperIndexSaveList = wxCommonCheckIndexService.getPaperIndexByHaopy(haopyReporData, papers);

        //批量保存
        riskPapersIndexService.saveBatch(paperIndexSaveList);


        //保存推荐药品
        wxPapersDrugsService.recommendDrugsByPaperIdNew(papers.getId());


        return ResponseUtil.ok(papers);
    } **/


    /**
     * 根据pdf解析得到json体检数据
     *
     * @param userId
     * @param pdfJson
     * @return
     * @throws Exception
     */
    @Transactional
    public Object createPaperByPdfJson(Integer userId, JSONObject pdfJson) throws Exception {

        if (Objects.isNull(pdfJson)) {

            ClassPathResource resource = new ClassPathResource("data/check_pdfjson.json");
            byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream());
            String str = new String(bytes, StandardCharsets.UTF_8);

            pdfJson = JSONObject.parseObject(str);
        }

        //基础信息
        JSONObject checkBaseInfo = pdfJson.getJSONObject("info");

        //基础信息
        JSONArray checkIndexArray = pdfJson.getJSONArray("data");


        if (Objects.isNull(checkBaseInfo) || Objects.isNull(checkIndexArray)) {
            return ResponseUtil.fail("未获取到体检数据");
        }

        AIRiskPapers papers = new AIRiskPapers();

        papers.setName(checkBaseInfo.getString("name"));
        papers.setUserId(userId);
        papers.setMobile(checkBaseInfo.getString(""));
        papers.setCheckDate(LocalDate.parse(checkBaseInfo.getString("date"), ConstDateFormatUtils.shortDateFormatCn));
        papers.setCheckNo(checkBaseInfo.getString("series"));
        Integer age = Integer.parseInt(checkBaseInfo.getString("age").replace("岁", "").replace(" ", ""));
        papers.setAge(age);
        papers.setSex(checkBaseInfo.getString("sex"));
        papers.setIndexParams(pdfJson);


        riskPapersService.save(papers);


        //*****************创建问卷选项**********************//


        List<AIRiskPapersOptions> listOptionsSave = createPaperTopicOptions(papers);


        //批量保存
        riskPapersOptionsService.saveBatch(listOptionsSave);

        //*****************创建问卷指标**********************//


        List<AIRiskPapersIndex> paperIndexSaveList = wxCommonCheckIndexService.getPaperIndexByPdfJson(checkIndexArray, papers);


        //批量保存
        riskPapersIndexService.saveBatch(paperIndexSaveList);

        //保存推荐药品
        wxPapersDrugsService.recommendDrugsByPaperIdNew(papers.getId());

        return ResponseUtil.ok(papers);
    }


    @Transactional
    public Object submitPaper(Integer paperId) {
        AIRiskPapers papers = riskPapersService.getById(paperId);
        if (Objects.isNull(papers)) {
            return ResponseUtil.failMsg("问卷信息不存在");
        }


        papers.setIsSubmit(Boolean.TRUE);

        riskPapersService.updateById(papers);


        List<AIRiskPapersIllness> listPapersIllness = riskPapersIllnessService.getByPapersId(paperId);

        for (AIRiskPapersIllness illnesItem : listPapersIllness) {

            Map<String, Object> params = new HashMap<>();
            //params.put("input", "血清尿酸，参考值：＜420μmol/L,实际值：438.00。   生活习惯因素：静坐时长，参考值：＜4小时,实际值：＞6小时 。 舒张压，参考值：60-89mmHg,实际值：81 。 运动锻炼因素：运动频度，参考值：经常参加,实际值：偶尔参加 。 胸部螺旋CT断层扫描，参考值：无异常,实际值：肺结节影。");
            String inputStr = "";


            /* ==========================指标输入 ============开始====================*/

            String checkIndexStr = getInputIndexStr(paperId, illnesItem.getIllnessId());

            System.out.println("指标输入：" + checkIndexStr);

            inputStr += checkIndexStr;

            /* ==========================问卷输入 ============开始====================*/


            String topStr = getTopicInputStr(paperId, illnesItem.getIllnessId());

            System.out.println("问卷输入：" + topStr);

            inputStr += topStr;


            if (!StringUtils.hasText(inputStr)) {
                illnesItem.setDeleted(Boolean.TRUE);
                continue;
            }
            if (inputStr.length() > AIChatParseDataUtil.AiInputLenghth) {
                inputStr = inputStr.substring(0, AIChatParseDataUtil.AiInputLenghth);
            }
            params.put("input", inputStr);
            illnesItem.setInputParams(params);

            //riskPapersIllnessService.save(papersIllness);

        }

        riskPapersIllnessService.updateBatchById(listPapersIllness);

        //异步请求
        paperIllnessToAISyncService.syncChatIllnessNew(paperId, listPapersIllness);


        return ResponseUtil.ok();


    }


    /**
     * 获取问卷参数字符串
     *
     * @param illnessId
     * @return
     */
    public String getTopicInputStr(Integer paperId, Integer illnessId) {
        String inputStr = "";
        List<AIRiskIllnessTopic> illnessTopList = riskIllnessTopicService.getByIllnessId(illnessId);
        for (AIRiskIllnessTopic illnesTopItem : illnessTopList) {
            try {
                if (Objects.isNull(illnesTopItem)) {
                    continue;
                }
                AIRiskPapersOptions papersOptionsItem = riskPapersOptionsService.getByOptionsPapersId(paperId, illnesTopItem.getTopicId());
                if (Objects.isNull(papersOptionsItem)) {
                    continue;
                }


                String topStr = "。" + papersOptionsItem.getTopicName();


                List<Map<String, Object>> options = papersOptionsItem.getOptions();
                String realStr = "：";
                String checkStr = "";
                for (Map<String, Object> optionsItem : options) {
                    if (optionsItem.get("checked").equals(Boolean.TRUE)) {
                        String checkValue = (String) optionsItem.get("value");
                        //不等于无
                        if (!Objects.equals(checkValue, "无")) {
                            checkStr += checkValue + "，";
                        }

                    }
                }
                if (StringUtils.hasText(checkStr)) {
                    checkStr = checkStr.substring(0, checkStr.length() - 1);
                    inputStr += topStr + realStr + checkStr;
                }
            } catch (Exception e) {
                log.error(e.toString());
            }


        }

        return inputStr;
    }

    /**
     * 获取指标参数字符串
     *
     * @param illnessId
     * @return
     */
    public String getInputIndexStr(Integer paperId, Integer illnessId) {
        String inputStr = "";
        List<AIRiskIllnessCheckIndex> illnessCheckIndexList = riskIllnessCheckIndexService.getByIllnessId(illnessId);
        for (AIRiskIllnessCheckIndex illnessCheckIndexItem : illnessCheckIndexList) {
            AIRiskPapersIndex papersIndexItem = riskPapersIndexService.getByPapersIndexByPaperId(paperId, illnessId, illnessCheckIndexItem.getIndexId());

            if (Objects.nonNull(papersIndexItem) && StringUtils.hasText(papersIndexItem.getIndexValue())) {

                if (!StringUtils.hasText(inputStr)) {
                    inputStr += papersIndexItem.getIndexName();
                } else {
                    inputStr += "。" + papersIndexItem.getIndexName();
                }

                //取疾病-指标关系的参考值
                //inputStr += papersIndexItem.getNormalVal();

                inputStr += "：" + papersIndexItem.getIndexValue();
            }


        }

        return inputStr;
    }


    /**
     * --------------------------创建问卷选项-------------------------------------------
     *
     * @param paper
     * @return
     */
    private List<AIRiskPapersOptions> createPaperTopicOptions(AIRiskPapers paper) {


        Short sex = Short.valueOf("0");
        if (paper.getSex().equals("男")) {
            sex = Short.valueOf("1");
        }
        if (paper.getSex().equals("女")) {
            sex = Short.valueOf("1");
        }


        List<AIRiskTopic> topics = riskTopicService.listActiveSexAll(sex);


        List<AIRiskPapersOptions> papersOptionsList = new ArrayList<>();

        topics.forEach(itemTop -> {
            List<AIRiskTopicOptions> options = riskTopicOptionsService.listByTopicId(itemTop.getId());

            if (Objects.nonNull(options) && options.size() > 0) {
                AIRiskPapersOptions papersOptions = new AIRiskPapersOptions();
                papersOptions.setPaperId(paper.getId());
                papersOptions.setTopicId(itemTop.getId());
                papersOptions.setTopicName(itemTop.getTopic());
                papersOptions.setIsMultiChoose(itemTop.getIsMultiChoice());
                List<Map<String, Object>> listArray = new ArrayList<>();
                options.forEach(optionsItem -> {
                    Map<String, Object> option = new HashMap<>();
                    option.put("name", optionsItem.getOptionName());
                    option.put("value", optionsItem.getOptionName());
                    option.put("checked", false);
                    listArray.add(option);
                });
                papersOptions.setOptions(listArray);
                papersOptionsList.add(papersOptions);
            }

        });
        List<AIRiskPapersOptions> listOptionsSave = new ArrayList<>();
        for (int i = 0; i < papersOptionsList.size(); i++) {
            AIRiskPapersOptions optionsItem = papersOptionsList.get(i);
            optionsItem.setSortIndex(i);
            listOptionsSave.add(optionsItem);
            //riskPapersOptionsService.save(optionsItem);
        }

        return listOptionsSave;
    }


}
